package org.springframework.sandbox.nettymvcpost.nettymvc;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletException;

public class DispatcherServletChannelInitializer extends ChannelInitializer<SocketChannel> {

	private final DispatcherServlet dispatcherServlet;

	public DispatcherServletChannelInitializer() throws ServletException {

		MockServletContext servletContext = new MockServletContext();
		MockServletConfig servletConfig = new MockServletConfig(servletContext);

		AnnotationConfigWebApplicationContext wac = new AnnotationConfigWebApplicationContext();
		wac.setServletContext(servletContext);
		wac.setServletConfig(servletConfig);
		wac.register(AppConfig.class);
		wac.refresh();

		this.dispatcherServlet = new DispatcherServlet(wac);
		this.dispatcherServlet.init(servletConfig);

		//set spring config in xml
		//this.dispatcherServlet = new DispatcherServlet();
		//this.dispatcherServlet.setContextConfigLocation("classpath*:/applicationContext.xml");
		//this.dispatcherServlet.init(servletConfig);
	}

	@Override
	public void initChannel(SocketChannel channel) throws Exception {
		// Create a default pipeline implementation.
		ChannelPipeline pipeline = channel.pipeline();

		// 新增，前缀为4个字节大小的int类型作为长度的解码器
		// 第一个参数是包最大大小
		// 第二个参数是长度值偏移量，由于编码时长度值在最前面，无偏移，此处设置为0
		// 第三个参数长度值占用的字节数，
		// 第四个参数是长度值的调节，假如请求包的大小是20个字节，长度值没包含本身的话应该是20，假如长度值包含了本身就是24，需要调整4个字节
		// 第五个参数,解析时候需要跳过的字节长,此处为4，跳过长度值字节数

		/*pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,
				0, 4, 0, 4));*/
		pipeline.addLast(new NettyMessageDecoder(Integer.MAX_VALUE,
				0, 4,0,4));

		//pipeline.addLast(new ByteToFullRequestDecoder());
		// 把接收到的Bytebuf数据包转换成String
		//pipeline.addLast(new StringDecoder());

		/*pipeline.addLast("decoder", new HttpRequestDecoder());
		pipeline.addLast("aggregator", new HttpObjectAggregator(65536));*/
		pipeline.addLast(new LengthFieldPrepender(4, false));
		pipeline.addLast(new FullHttpResponseToStringEncoder());
	//	pipeline.addLast("encoder", new HttpResponseEncoder());
		pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
		//传递的参数为 FullHttpRequest
		pipeline.addLast("handler", new ServletNettyHandler(this.dispatcherServlet));
	}

}
